import re, commands

def __theHardWay__():

	import sys, os
	#  based on methods collected in
	#  woof -- an ad-hoc single file webserver by Simon Budig  <simon@budig.de>
	#  http://www.home.unix-ag.org/simon/woof.html
	# With contributions from:
	# Darwin support with the help from Mat Caughron, <mat@phpconsulting.com>
	# Solaris support by Colin Marquardt, <colin.marquardt@zmd.de>
	# FreeBSD support with the help from Andy Gimblett, <A.M.Gimblett@swansea.ac.uk>

	opts = {
		"Linux":{'netstat':'-rn','defgateway':'0.0.0.0','ifconfkey':'inet addr:'},
		"Darwin":{'netstat':'-rn','defgateway':'default','ifconfkey':'inet '},
		"FreeBSD":{'netstat':'-rn','defgateway':'default','ifconfkey':'inet '},
		"SunOS":{'netstat':'-arn','defgateway':'0.0.0.0','ifconfkey':'inet '},
		}

	os.environ["PATH"] = "/sbin:/usr/sbin:/usr/local/sbin:" + os.environ["PATH"]
	try:
		opt = opts[os.uname()[0]]
	except:
		print >>sys.stderr, "Unsupported platform for interface and gateway IP detection.";
		opt = {}

	device = ''
	gatewayip = ''
	ip = ''
	if opt:
		routing = commands.getoutput("LC_MESSAGES=C netstat "+opt['netstat']).splitlines()
		for i in routing:
			if len(i)>2:
				i = i.split()
				if i[0] == opt['defgateway']:
					device = i[-1]
					gatewayip = i[1]
					try:
						ip = re.search('(?<='+opt['ifconfkey']+')[\d\.]+',commands.getoutput ("LC_MESSAGES=C ifconfig "+device)).group()
					except:
						pass
					break
	
	#on OpenSuse (may be other distros?) ifconfig is NOT available to regular users.
	#hence, my attempt to to use the /procfs.
	#note, from now on, were are looking only on TCP connections. ppp (dialup and some DSL) might not work.
	if not ip:
		# we will shake /proc/net/tcp for number.
		try:
			tcp = open('/proc/net/tcp').readlines()
		except:
			tcp = []
		try:
			col = tcp.pop(0).split().index('local_address')
		except:
			col = 1 # column may be translated, but it is usually #2 (#1 in list)
		ips = []
		for line in tcp:
			try:
				i = line.strip().split()[col].split(':',1)[0] # usually this results in: 6701A8C0:0AC1
			except:
				i = ''
			if not (i in ['0100007F','']): ips.append(i) # 0100007F =  127.0.0.1 = localhost. these are hex.
		if ips:
			# short description of what happens:
			# 1. i don't know which ip to choose (if there are more than 1). Let's pick 1st.
			# 2. Convert parts into int, string.
			# 3. Reverse and reassemble.
			a = [str(int(ips[0][i*2:i*2+2],16)) for i in range(ips[0].__len__()/2)] # now, ['101','1','168','192']
			a.reverse()
			ip = '.'.join(a)

	if not ip or not gatewayip:
		# well, i tried, i really, really tried
		print >>sys.stderr, "Failed to detect interface and gateway IP.";
	return (ip, gatewayip)

def getIP():
	'''
	Very simple weapper for nm-tool - NetworkManager command-line util.
	The goal is to process the output for this machine's and gateway IP.
	Returns (our_ip, gateway_ip), both as strings
	'''
	a = commands.getoutput('nm-tool')
	try:
		stat = re.search('(?<=State: ).+',a).group()
	except:
		stat = ''
	
	clientip = ''
	gatewayip = ''
	if stat == 'connected':
		spans = []
		# identifying device sections.
		for i in re.finditer('- [\w\d: ]+ [-]+',a):
			spans.append(i.start())
			spans.append(i.end())
		spans.append(a.__len__())
		spans.pop(0) # this makes the list start with the clean start of the 1st section.
		# now we will take pairs of numbers and crop the parts out.
		devices = []
		for i in range(int(spans.__len__()/2)):
			devices.append(a[spans[i*2]:spans[(i*2)+1]])
		for device in devices:
			try:
				stat = re.search('(?<=Active:)[ \w]+',device).group().strip()
			except:
				stat = ''
			if stat == 'yes':
				try:
					clientip = re.search('(?<=IP Address:)[ \w\.]+',a).group().strip()
					gatewayip = re.search('(?<=Gateway:)[ \w\.]+',a).group().strip()
				except:
					pass
	if not clientip or not gatewayip:
		# UGH!!!! Rats.... Back to the hand-cranked way.
		clientip, gatewayip = __theHardWay__()
	return clientip, gatewayip

def natIP(ip):
	'''
	Returns True if IP is from one of "NAT" groups
	'''
	return bool(re.match('10\..+|172.16.+|192.168\..+|127\..+', ip))
